package BuildTrainSet.AssignTag;

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashSet;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLOutputFactory;
import javax.xml.stream.XMLStreamConstants;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;
import javax.xml.stream.XMLStreamWriter;

/**
 *
 * @author phamthanh
 * Gán thẻ alpha cho file, những nsw nào là một từ trong từ điển thì bỏ thẻ nsw của nó.
 */
public final class AlphaTag {

    private ArrayList conAr = new ArrayList();
    public HashSet wordAr = new HashSet();
    public ArrayList<String> greekAr = new ArrayList<String>();

    public AlphaTag(String inF, String ouF) throws ClassNotFoundException, SQLException, UnsupportedEncodingException, XMLStreamException, FileNotFoundException, IOException {

        System.out.println("package BuildTrainSet.AssignTag; class AlphaTag");

        setConAr();
        setWordAr();
        setGreek();
        createAlphaTagFile(inF, ouF);
    }

    public void createAlphaTagFile(String inF, String ouF) throws XMLStreamException, IOException {
        long startTime = System.currentTimeMillis();
        System.out.println("Dang gan the alpha...");
        int aswd = 0;
        int expn = 0;
        int seqn = 0;
        FileInputStream fis = new FileInputStream(inF);
        XMLStreamReader xmlStreamReader = XMLInputFactory.newInstance().createXMLStreamReader(fis);

        FileOutputStream fos = new FileOutputStream(ouF);
        OutputStreamWriter osw = new OutputStreamWriter(fos, "UTF8");
        XMLStreamWriter xmlStreamWriter = XMLOutputFactory.newInstance().createXMLStreamWriter(osw);
        xmlStreamWriter.writeStartElement("root");
        while (xmlStreamReader.hasNext()) {
            int eventCode = xmlStreamReader.next();
            switch (eventCode) {

                case XMLStreamConstants.START_ELEMENT:
                    String localName = xmlStreamReader.getLocalName();
                    if (localName.equals("record")) {
                        String RecId = xmlStreamReader.getAttributeValue(0);
                        xmlStreamWriter.writeStartElement(localName);
                        xmlStreamWriter.writeAttribute("RecId", RecId);
                    }
                    if (localName.equals("URL")) {
                        String url = xmlStreamReader.getElementText();

                        xmlStreamWriter.writeStartElement(localName);
                        xmlStreamWriter.writeCharacters(url);
                        xmlStreamWriter.writeEndElement();
                    }
                    if (localName.equals("Infomation")) {
                        xmlStreamWriter.writeStartElement(localName);
                    }

                    if (localName.equals("W")) {

                        String atVal = xmlStreamReader.getAttributeValue(0);
                        if (atVal.equals("ALPHA")) {
                            String nsw = xmlStreamReader.getElementText();
                            String nswLower = nsw.toLowerCase();
                            if (isWord(nswLower)) {
                                xmlStreamWriter.writeCharacters(nsw + " ");
                            } else {
                                String atAlVal = detectAlphaTag(nsw);
                                xmlStreamWriter.writeStartElement(localName);

                                xmlStreamWriter.writeAttribute("NSW", atAlVal);
                                xmlStreamWriter.writeCharacters(nsw);
                                xmlStreamWriter.writeEndElement();

                                if (atAlVal.equals("ASWD")) {
                                    aswd++;
                                } else {
                                    if (atAlVal.equals("EXPN")) {
                                        expn++;
                                    } else {
                                        seqn++;
                                    }
                                }
                            }
                        } else {
                            xmlStreamWriter.writeStartElement(localName);
                            xmlStreamWriter.writeAttribute("NSW", atVal);
                            String nsw = xmlStreamReader.getElementText();
                            xmlStreamWriter.writeCharacters(nsw);
                            xmlStreamWriter.writeEndElement();
                        }

                    }

                    if (localName.equals("SPLIT")) {
                        xmlStreamWriter.writeStartElement(localName);
                    }
                    break;


                case XMLStreamConstants.END_ELEMENT:
                    String endLocalName = xmlStreamReader.getLocalName();

                    if (endLocalName.equals("record")) {
                        xmlStreamWriter.writeEndElement();
                    }
                    if (endLocalName.equals("Infomation")) {
                        xmlStreamWriter.writeEndElement();
                    }

                    if (endLocalName.equals("SPLIT")) {
                        xmlStreamWriter.writeEndElement();
                    }

                    break;
                case XMLStreamConstants.CHARACTERS:
                    String character = xmlStreamReader.getText();
                    xmlStreamWriter.writeCharacters(character);
                    break;

                default:
                    break;
            }
        }
        xmlStreamWriter.writeEndElement();

        xmlStreamReader.close();
        xmlStreamWriter.close();
        fis.close();
        fos.close();

        System.out.println("    +aswd: " + aswd);
        System.out.println("    +expn: " + expn);
        System.out.println("    +seqn: " + seqn);
        long endTime = System.currentTimeMillis();
        long time = endTime - startTime;
        System.out.println("Thoi gian gan the alpha la: " + time);

    }

    public boolean haveUperCase(String nsw) {
        for (int i = 0; i < nsw.length(); i++) {
            if (Character.isUpperCase(nsw.charAt(i))) {
                return true;
            }
        }
        return false;
    }

    public boolean haveLowerCase(String nsw) {
        for (int i = 0; i < nsw.length(); i++) {
            if (Character.isLowerCase(nsw.charAt(i))) {
                return true;
            }
        }
        return false;

    }

    public boolean haveConsonant(String nsw) {
        for (int i = 0; i < nsw.length(); i++) {
            if (conAr.contains(nsw.subSequence(i, i + 1))) {
                return true;
            }
        }
        return false;

    }

    public boolean haveVowel(String nsw) {
        for (int i = 0; i < nsw.length(); i++) {
            if (!conAr.contains(nsw.subSequence(i, i + 1))) {
                return true;
            }
        }
        return false;

    }

    public boolean isAswd(String nsw) {
        if (haveConsonant(nsw) && haveLowerCase(nsw) && haveVowel(nsw)) {
            return true;
        }
        return false;

    }

    public boolean isExpn(String nsw) {
//       if(nsw.equals("%")||nsw.equals("Đ")||nsw.equals("VNĐ")||nsw.equals("$")){
//           return true;
//       }
        if (nsw.length() == 1) {
            if (Character.isUpperCase(nsw.charAt(0))) {
                if (nsw.equals("P") || nsw.equals("Q")) {
                    return true;
                } else {
                    return false;
                }
            } else {
                return true;
            }
        }
        if (haveVowel(nsw)) {
            return false;
        }
//        if(haveLowerCase(nsw)){
//            return false;
//        }
        return true;
    }

    public boolean isWord(String nsw) {
        if (wordAr.contains(nsw)) {
            return true;
        }
//        if(nsw.equals("'")){
//            return true;
//        }
        return false;
    }

    public boolean isGreekNumber(String nsw) {
        if (greekAr.contains(nsw)) {
            return true;
        }
        return false;
    }

    public String detectAlphaTag(String nsw) {
        if (isGreekNumber(nsw)) {
            return "Greek";
        }
        if (isAswd(nsw)) {
            return "ASWD";
        }
        if (isExpn(nsw)) {
            return "EXPN";
        }

        return "SEQN";
    }

    public void setConAr() throws UnsupportedEncodingException, FileNotFoundException, IOException {
//        conAr.add("B");
//        conAr.add("C");
//        conAr.add("D");
//        conAr.add("Đ");
//        conAr.add("G");
//        conAr.add("H");
//        conAr.add("K");
//        conAr.add("L");
//        conAr.add("M");
//        conAr.add("N");
//        conAr.add("P");
//        conAr.add("Q");
//        conAr.add("S");
//        conAr.add("T");
//        conAr.add("V");
//        conAr.add("X");
//        conAr.add("Y");
//        conAr.add("Z");        
//        conAr.add("b");
//        conAr.add("c");
//        conAr.add("d");
//        conAr.add("đ");
//        conAr.add("g");
//        conAr.add("h");
//        conAr.add("k");
//        conAr.add("l");
//        conAr.add("m");
//        conAr.add("n");
//        conAr.add("p");
//        conAr.add("q");
//        conAr.add("s");
//        conAr.add("t");
//        conAr.add("v");
//        conAr.add("x");
//        conAr.add("y");
//        conAr.add("z");       
        BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream("resources\\Consonant.db"), "UTF8"));
        String Consonant;
        int i = 0;
        while ((Consonant = br.readLine()) != null) {
            conAr.add(Consonant);
//            i++;
        }
//        System.out.println(i);
    }

    public void setGreek() throws UnsupportedEncodingException, FileNotFoundException, IOException {
//        greekAr.add("I");
//        greekAr.add("II");
//        greekAr.add("III");
//        greekAr.add("IV");
//        greekAr.add("V");
//        greekAr.add("VI");
//        greekAr.add("VII");
//        greekAr.add("VIII");
//        greekAr.add("IX");
//        greekAr.add("X");
//        greekAr.add("XI");
        BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream("resources\\greekNumber.db"), "UTF8"));
        String greekNumber;
        int i = 0;
        while ((greekNumber = br.readLine()) != null) {
            greekAr.add(greekNumber);
//            i++;
        }
//        System.out.println(i);
    }

    public void setWordAr() throws UnsupportedEncodingException, FileNotFoundException, IOException {
        BufferedReader bra = new BufferedReader(new InputStreamReader(new FileInputStream("resources\\amtiet.txt"), "UTF16"));
        String amtiet;

        while ((amtiet = bra.readLine()) != null) {
            wordAr.add(amtiet);
        }
    }
}
